import 'package:flutter/foundation.dart';
import 'package:loxen/api/api.dart';
import 'package:loxen/api/http_server/dictionaries.dart';
import 'package:loxen/api/http_server/file_collection.dart';
import 'package:loxen/api/http_server/user_comment.dart';
import 'package:loxen/api/http_server/user_follower.dart';
import 'package:loxen/api/http_util.dart';
import 'package:loxen/mode/base_mode.dart';
import 'package:loxen/mode/comment_list.dart';
import 'package:loxen/mode/comment_mode.dart';
import 'package:loxen/mode/inspiration/inspiration_info_bean.dart';
import 'package:loxen/mode/inspiration/inspiration_list.dart';
import 'package:loxen/utils/html_util.dart';
import 'package:loxen/utils/string_res.dart';
import 'package:loxen/viewmode/base_view_model.dart';
import 'package:loxen/api/http_server/like.dart';
import 'package:rxdart/rxdart.dart';

class InspirationDetailViewMode extends BaseViewModel
    with LikeMixin, FileCollectionMixin, UserFollowerMixin, UserCommentMixin {
  InspirationInfo _contentBean;

  //外部的对象
  InspirationInfo _pInspirationInfo;
  List<InspirationInfo> likeInspirations;

  InspirationDetailViewMode(this._pInspirationInfo);

  int pageSize = 3;
  bool isNextComment = false;
  int _opacity = 0;
  int _commentPage = 1;
  double _presetOffset = 200.0;

  int get opacity => _opacity;

  InspirationInfo get contentBean => _contentBean;

  List<Comment> comments = [];

  int commentCount;

  void changeEntity() {
    notifyListeners();
  }

  void collectionArticle() {
    _contentBean.collect_num += 1;
    _contentBean.is_collect = 1;
    _pInspirationInfo.collect_num += 1;
    _pInspirationInfo.is_collect = 1;
    notifyListeners();
  }

  void unCollectionArticle({Function(String msg) onShow}) {
    unCollection(ContentType.IDEA_ARTICLE, _pInspirationInfo.id.toString()).listen((event) {
      if (event == 200) {
        _contentBean.is_collect = 0;
        _contentBean.collect_num -= 1;
        _pInspirationInfo.is_collect = 0;
        _pInspirationInfo.collect_num -= 1;
        if (onShow != null) onShow.call(StringResources.qu_xiao_shou_cang);
        notifyListeners();
      } else {
        if (onShow != null) onShow.call(StringResources.qu_xiao_shou_cang_shi_bai);
      }
    }, onError: (error, stack) {
      if (onShow != null) onShow.call(StringResources.wang_luo_yi_chang);
      print(error);
      print(stack);
    });
  }

  void likeUnCollection(InspirationInfo likeInspiration) {
    unCollection(ContentType.IDEA_ARTICLE, likeInspiration.id.toString()).listen((event) {
      if (event == 200) {
        likeInspiration.is_collect = 0;
        likeInspiration.collect_num -= 1;
        notifyListeners();
      }
    }, onError: (error, stack) {
      print(error);
      print(stack);
    });
  }

  ///[comment] 回复某人  [params] 一级评论
  void commentToComment(Comment comment, String content,
      {Function(String msg) onError, Comment params}) {
    commentToSB(_pInspirationInfo.id.toString(), content,
            parent: params != null ? params.id.toString() : comment.id.toString(),
            previousComment: comment.id.toString())
        .listen((event) {
      if (event != null) {
        List<Comment> list = [];
        list.add(event);
        if (params == null) {
          comment.sub_comment_num += 1;
          if (comment.sub_comment != null) {
            list.addAll(comment.sub_comment);
          }
          comment.sub_comment = list;
          commentCount += 1;
        } else {
          params.sub_comment_num += 1;
          if (params.sub_comment != null) {
            list.addAll(params.sub_comment);
          }
          params.sub_comment = list;
          commentCount += 1;
        }
        notifyListeners();
      } else {
        if (onError != null) onError.call('评论失败');
      }
    }, onError: (error) {
      if (error is ServiceException) {
        var map = error.data as Map;
        if (onError != null) onError.call(map['data']['instance_id'].toString());
      }
    });
  }

  //评论当前文章
  void commentThis(String content, {Function(String msg) onError}) {
    commentToSB(_pInspirationInfo.id.toString(), content).listen((event) {
      if (event != null) {
        List<Comment> list = [event];
        list.addAll(comments);
        comments = list;
        _contentBean.comment_num += 1;
        _pInspirationInfo.comment_num += 1;
        commentCount += 1;
        notifyListeners();
      } else {
        if (onError != null) onError.call('评论失败');
      }
    }, onError: (error) {
      print(error);
      if (error is ServiceException) {
        var map = error.data as Map;
        if (onError != null) onError.call(map['data']['instance_id'].toString());
      }
    });
  }

  //关注当前文章作者
  void followThisUser({Function(String error) onError}) {
    followerUser(_contentBean.user.id.toString()).listen((event) {
      if (event == 201) {
        _contentBean.user.isFollowed = 1;
        notifyListeners();
      } else {
        if (onError != null) onError.call('关注失败');
      }
    }, onError: (error, stack) {
      print(error);
      print(stack);
      if (onError != null) onError.call('网络异常');
    });
  }

  //取消关注当前文章作者
  void unFollowThisUser({Function(String error) onError}) {
    unFollowerUser(_contentBean.user.id.toString()).listen((event) {
      if (event == 200) {
        _contentBean.user.isFollowed = 0;
        notifyListeners();
      } else {
        if (onError != null) onError.call('取消失败');
      }
    }, onError: (error, stack) {
      print(error);
      print(stack);
      if (onError != null) onError.call('网络异常');
    });
  }

  //当前文章点赞
  void likeThis() {
    like(ContentType.IDEA_ARTICLE, _contentBean.id.toString()).listen((event) {
      if (event != null) {
        _contentBean.is_like = 1;
        _contentBean.like_num = event.like_num;
        _pInspirationInfo.is_like = 1;
        _pInspirationInfo.like_num = event.like_num;
        notifyListeners();
      }
    }, onError: (error, stack) {
      print(stack);
      print(error);
    });
  }

  //当前文章取消点赞
  void unLikeThis() {
    unLike(ContentType.IDEA_ARTICLE, _contentBean.id.toString()).listen((event) {
      if (event != null) {
        _contentBean.is_like = 0;
        _contentBean.like_num = event.like_num;
        _pInspirationInfo.is_like = 0;
        _pInspirationInfo.like_num = event.like_num;
        notifyListeners();
      }
    }, onError: (error, stack) {
      print(stack);
      print(error);
    });
  }

  //猜你喜欢文章点赞
  void likeToLikeInspiration(InspirationInfo likeInspiration) {
    like(ContentType.IDEA_ARTICLE, likeInspiration.id.toString()).listen((event) {
      if (event != null) {
        likeInspiration.is_like = 1;
        likeInspiration.like_num = event.like_num;
        notifyListeners();
      }
    }, onError: (error, stack) {
      print(stack);
      print(error);
    });
  }

  //猜你喜欢文章取消点赞
  void unLikeToLikeInspiration(InspirationInfo likeInspiration) {
    unLike(ContentType.IDEA_ARTICLE, likeInspiration.id.toString()).listen((event) {
      if (event != null) {
        likeInspiration.is_like = 0;
        likeInspiration.like_num = event.like_num;
        notifyListeners();
      }
    }, onError: (error) => print(error));
  }

  void loadLikeInspiration() {
    ApiService.likeInspiration("${_contentBean.category}", "${_contentBean.id}")
        .flatMap((value) => compute(decodeLikeInspiration, value.data).asStream())
        .listen((event) {
      likeInspirations = event.data.results;
    }, onError: (error) => print(error), onDone: () => notifyListeners());
  }

  //取消点赞
  void unLikeCommentArticle(String id, Function() success) {
    unLikeComment(id).listen((event) {
      if (event == 200) {
        success.call();
        notifyListeners();
      }
    }, onError: (error) => print(error));
  }

  //评论点赞
  void likeCommentArticle(String id, Function() success) {
    likeComment(id).listen((event) {
      if (event == 201) {
        success.call();
        notifyListeners();
      }
    }, onError: (error) => print(error));
  }

  //标题栏透明度
  void changeColor(double offset) {
    _opacity = offset > _presetOffset ? 255 : offset * 255 ~/ _presetOffset;
    notifyListeners();
  }

  void deleteCommentNotify(Comment comment,
      {Function(String msg) onError, bool isSub = false, Comment params}) {
    deleteComment('idea-article', contentBean.id.toString(), comment.id.toString()).listen((event) {
      if (event == 200) {
        if (isSub) {
          var subList = params.sub_comment;
          subList.remove(comment);
          params.sub_comment = subList.take(subList.length).toList();
        } else {
          comments.remove(comment);
          comments = comments.take(comments.length).toList();
        }
        commentCount -= 1;
        notifyListeners();
      } else {
        if (onError != null) onError.call("删除失败！");
      }
    }, onError: (error) {
      if (onError != null) onError.call("网络异常");
      print(error);
    });
  }

  //是否有下一页子评论
  bool isNextSubComment(Comment comment) {
    return comment.subPage * pageSize < comment.sub_comment_num;
  }

  void nextSubComment(Comment comment) {
    if (isNextSubComment(comment)) {
      comment.subPage += 1;
      loadSubComment(comment);
    }
  }

  //加载子评论列表
  void loadSubComment(Comment comment) {
    ApiService.commentList("${comment.id}", "${comment.subPage}", pageSize: pageSize.toString())
        .flatMap((value) => compute(decodeComment, value.data).asStream())
        .listen((event) {
      List<Comment> newList = [];
      newList.addAll(comment.sub_comment);
      newList.addAll(event.data.results);
      comment.sub_comment = newList;
    }, onError: (error) => print(error), onDone: () => notifyListeners());
  }

  //下一页评论数据
  void nextComment() {
    if (isNextComment) {
      _commentPage++;
      loadComment();
    }
  }

  //加载评论数据
  void loadComment() {
    ApiService.inspirationComment(_pInspirationInfo.id.toString(), "$_commentPage",
            pageSize: pageSize.toString())
        .flatMap((value) => compute(decodeComment, value.data).asStream())
        .listen(
      (event) {
        if (event.data.next != null && event.data.next.trim() != '') {
          isNextComment = true;
        } else {
          isNextComment = false;
        }
        List<Comment> newList = [];
        event.data.results.forEach((element) {
          element.sub_comment = [];
          loadSubComment(element);
        });
        newList.addAll(comments);
        newList.addAll(event.data.results);
        comments = newList;
      },
      onError: (error) => print(error),
      onDone: () => notifyListeners(),
    );
  }

  void loadData() {
    Rx.zip2<BaseMode<InspirationInfo>, BaseMode<CommentList>, Future>(
        loadContent1(), loadComment1(), (a, b) async {
      if (a.data != null) {
        _contentBean = a.data;
        commentCount = _contentBean.comment_num;
        loadLikeInspiration();
        _contentBean.contentList = await HtmlUtil.parseHtml(_contentBean.content);
        _contentBean.content = null;
        mState = BaseState.CONTENT;
      } else {
        mState = BaseState.EMPTY;
      }

      if (b.data.next != null && b.data.next.trim() != '') {
        isNextComment = true;
      }
      comments = b.data.results;
      comments.forEach((element) {
        element.sub_comment = [];
        loadSubComment(element);
      });
      return 200;
    }).doOnListen(() {
      mState = BaseState.LOADING;
      notifyListeners();
    }).listen((event) {},
        onError: (error) {
          print(error);
          mState = BaseState.FAIL;
        },
        onDone: () => notifyListeners());
  }

  Stream<BaseMode<CommentList>> loadComment1() {
    return ApiService.inspirationComment(_pInspirationInfo.id.toString(), "$_commentPage",
            pageSize: pageSize.toString())
        .flatMap((value) => compute(decodeComment, value.data).asStream());
  }

  Stream<BaseMode<InspirationInfo>> loadContent1() {
    return ApiService.inspirationContent(_pInspirationInfo.id.toString())
        .flatMap((value) => compute(decodeContent, value.data).asStream());
  }

  static BaseMode<Comment> decodeSendComment(dynamic json) {
    return BaseMode<Comment>(json);
  }

  static BaseMode<InspirationInfoList> decodeLikeInspiration(dynamic json) {
    return BaseMode<InspirationInfoList>(json);
  }

  static BaseMode<CommentList> decodeComment(dynamic json) {
    return BaseMode<CommentList>(json);
  }

  static BaseMode<InspirationInfo> decodeContent(dynamic json) {
    return BaseMode<InspirationInfo>(json);
  }
}
